package com.itheima.tanhua.server.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.itheima.commons.holder.TokenHolder;
import com.itheima.tanhua.dubbo.api.TanhuaService;
import com.itheima.tanhua.dubbo.api.UserService;
import com.itheima.tanhua.model.domain.UserInfo;
import com.itheima.tanhua.model.dto.RecommendationDto;
import com.itheima.tanhua.model.vo.TodayBestVo;
import com.itheima.tanhua.server.utils.StringsUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.awt.*;
import java.util.*;
import java.util.List;

/**
 * @author itheima
 * @since 2022-01-14
 */
@RestController
@RequestMapping("tanhua")
public class TanhuaController {

    @DubboReference
    private UserService userService;

    @DubboReference
    private TanhuaService tanhuaService;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * Day03 今日佳人
     * 随机获取同城市用户
     * 不能出现我
     * 缘分值随机90~99
     *
     * @return ResponseEntity
     */
    @GetMapping("todayBest")
    public ResponseEntity todayBest() {

        String userId = TokenHolder.getUserId();

        // 步骤一：先查出当前用户信息（因为需要获取当前用户所在城市）
        UserInfo myUserInfo = userService.getUserInfoById(userId);
        if (Objects.isNull(myUserInfo)) {
            TodayBestVo todayBestVo = new TodayBestVo("1",
                    "https://hbimg.huabanimg.com/3ec69aeea6ebd7f039caf83cf8fb8926bab3df71a3ee1-z195dg_fw658/format/webp",
                    "随机",
                    "woman",
                    18,
                    null,
                    99);
            return ResponseEntity.ok(todayBestVo);
        }

        // 步骤二：获取当前用户所在城市
        String myCity = myUserInfo.getCity();

        // 步骤三：查询与当前用户同城的用户（随机获取）
        UserInfo todayBestUserInfo = tanhuaService.randomUserByCity(userId, myCity);

        // 将list数据转为用,分割的字符串
        // 少女,xx
        String tagString = todayBestUserInfo.getTagString();
        List<String> tagList = StringsUtils.string2List(tagString);

        // 组装数据
        TodayBestVo vo = new TodayBestVo();
        BeanUtils.copyProperties(todayBestUserInfo, vo);
        vo.setTags(tagList);

        // 随机缘分值
        vo.setFateValue(RandomUtil.randomInt(90, 99));

        return ResponseEntity.ok(vo);
    }


    private ResponseEntity recommend() {
        String id = TokenHolder.getUserId();

        // 步骤一：获取当前用户所在城市
        UserInfo myUserInfo = userService.getUserInfoById(id);
        if (Objects.isNull(myUserInfo)) {
            TodayBestVo todayBestVo = new TodayBestVo("1",
                    "https://hbimg.huabanimg.com/3ec69aeea6ebd7f039caf83cf8fb8926bab3df71a3ee1-z195dg_fw658/format/webp",
                    "随机",
                    "woman",
                    18,
                    null,
                    99);
            return ResponseEntity.ok(todayBestVo);
        }

        // 步骤二：获取当前用户所在城市
        String myCity = myUserInfo.getCity();

        // 步骤三：
        // 获取我当前用户所在城市的用户
        // 根据注册时间进行排序
        // 排除当前用户
        List<UserInfo> recommendUserList = tanhuaService.findRecommendUserList(id, myCity, null);
        if (CollUtil.isEmpty(recommendUserList)) {
            return ResponseEntity.ok(null);
        }

        for (UserInfo userInfo : recommendUserList) {
            if (Objects.isNull(userInfo)) {
                continue;
            }

            // 年轻,诱惑力
            String tagString = userInfo.getTagString();
            if (StringUtils.isEmpty(tagString)) {
                continue;
            }

            List<String> tagList = StringsUtils.string2List(tagString);

            userInfo.setTags(tagList);
        }
        return ResponseEntity.ok(recommendUserList);
    }

    /**
     * Day04 获取首页推荐用户列表
     *
     * @return ResponseEntity
     */
    @GetMapping("/recommendation")
    public ResponseEntity getRecommendationList(RecommendationDto dto) {
        // 步骤一：获取我的id
        String myUserId = TokenHolder.getUserId();

        // 步骤二：通过我的id获取我当前的坐标位置
        List<Point> geo1 = redisTemplate.boundGeoOps("geo").position(myUserId);
        if (CollUtil.isEmpty(geo1)) {
            return ResponseEntity.ok(null);
        }

        // 步骤三：获取我的第一组坐标
        double x = geo1.get(0).getX();
        double y = geo1.get(0).getY();

        // 步骤四：设置半径长度
        // 参数一：半径长度
        // 参数二：半径单位
        Distance distance = new Distance(10, Metrics.KILOMETERS);

        // 步骤五：设置圆心坐标
        Point point = new Point(x, y);

        // 步骤六：画圆圈
        // Circle(参数一：坐标点， 参数二：半径）
        Circle circle = new Circle(point, distance);

        // 步骤七：设置排序规则和获取数据个数
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        args.sortAscending()
                .includeCoordinates()
                .includeDistance()
                .limit(10);

        // 步骤八：搜索圆圈内所有坐标点 radius(参数一：圆圈，参数二：排序)
        GeoResults<RedisGeoCommands.GeoLocation<String>> geo = redisTemplate.boundGeoOps("geo").radius(circle, args);

        // 3. 根据获取到的用户，到数据库查询他们的用户信息
        // 1,2,3

        if (CollUtil.isEmpty(geo)) {
            return ResponseEntity.ok(null);
        }

        // 步骤九：获取圆圈内所有坐标点，对应的用户id
        List<String> list = new ArrayList<>();
        for (GeoResult<RedisGeoCommands.GeoLocation<String>> result : geo) {
            RedisGeoCommands.GeoLocation<String> location = result.getContent();

            // 坐标的名称（用户id）
            String userId = location.getName();

            // 坐标经纬度
            Point pointx = location.getPoint();

            System.out.println(pointx);

            Map<String, Object> map = new HashMap<>();
            map.put("name", userId);
            map.put("x", pointx.getX());
            map.put("y", pointx.getY());
            list.add(userId);
        }

        // 步骤十：根据上一步获取到的userId，到数据库中查询对应的用户信息
        List<UserInfo> userInfoInIdList = userService.getUserInfoInIdList(list);

        return ResponseEntity.ok(userInfoInIdList);
    }
}